// kate: space-indent on; indent-width 8;
.var SPEED = 25
.var SID = 54272
.var SNAKECHAR = 81
.var GetReadyX = 141 //(320-96)/2
.var music = LoadSid("Ghosts_n_Goblins.sid")
.pc =$0801 "Basic Upstart Program"
:BasicUpstart($0810)

.pc = $0810 "Main Program"
        jsr init
        jsr mainloop
        rts
        
        
init:   lda #0 
        sta $d020
        sta $d021
        jsr clrscrn
        ldx #0
        ldy #0
        lda #music.startSong-2
        jsr music.init  
        rts
        
clrscrn:
        ldx #0
        lda #' '
!loop:
        .for(var i=0; i<4; i++) {
                sta $0400+i*$100,x
        }
        inx
        bne !loop-
        ldx #0
ilp:    lda info,x
        beq tdone
        sta $400,x
        inx
        bne ilp
tdone:        
        lda #GetReadyX+0*24
        sta $d000
        lda #GetReadyX+1*24
        sta $d002
        lda #GetReadyX+2*24
        sta $d004
        lda #GetReadyX+3*24
        sta $d006
        
        lda #150-21/2
        sta $d001
        sta $d003
        sta $d005
        sta $d007
        
        lda #1
        sta $d027
        sta $d028
        sta $d029
        sta $d02A
        
        ldy #$3000/64
        sty $400+$3f8
        iny
        sty $400+$3f9
        iny
        sty $400+$3fA
        iny
        sty $400+$3fB
        lda #%00001111
        sta $d015
        lda #0
        sta $d010       //MSB bits of X
        rts

mainloop:
        jsr waitframe
        inc $d020
        jsr music.play
        inc $d020
        jsr scan_keyboard
        jsr move
        lda #0
        sta $d020
        jmp mainloop
        
        
waitframe: {
        lda #80
loop:   cmp $d012
        bne loop
loop2:  cmp $d012
        beq loop2
}


        // keyboard scanning taken from
        // https://github.com/cjauvin/tetris-c64/blob/master/tetris.asm
scan_keyboard: 
        // non-debounced keys (A/D)
        
        lda #$fd // check A key
        sta $dc00
        lda $dc01
        cmp #$fb
        bne *+5
        jmp do_left

        lda #$fb // check D key
        sta $dc00
        lda $dc01
        cmp #$fb
        bne *+5 // beq do_right is too far!
        jmp do_right
        
        lda #$fd // w
        sta $dc00
        lda $dc01
        cmp #$fd
        bne *+5
        jmp do_up
        
        lda #$fd // check for not-S (i.e. S release)
        sta $dc00
        lda $dc01
        cmp #$df
        bne *+5        
        jmp do_down
        rts
        
do_left: lda vel
        cmp #$1
        beq lexit
        lda #$ff
        sta vel
        sta vel+1
lexit:  rts
        
do_right: 
        lda vel
        cmp #$ff
        beq rexit
        lda #$01
        sta vel
        lda #0
        sta vel+1
rexit:  rts

do_up:  lda vel
        cmp #40
        beq uexit
        lda #256-40
        sta vel
        lda #$ff
        sta vel+1
uexit:  rts
        
do_down: lda vel
        cmp #256-40
        beq dexit
        lda #40
        sta vel
        lda #0
        sta vel+1
dexit:  rts
        
        
move:   {
        dec mframe
        beq ttm
        rts
ttm:    lda #SPEED
        sta mframe
        //jsr msound
        
        clc
        lda pos
        adc vel
        sta pos
        sta foo+1
        lda pos+1
        adc vel+1
skip:   sta pos+1
        sta foo+2
        
        lda #SNAKECHAR
foo:    sta $1234
        lda slen
        asl 
        tay
        lda snake,y
        sta foo2+1
        iny
        lda snake,y
        sta foo2+2
        lda #' '
foo2:   sta 12345
        
        //scroll the block 'up'
        lda slen
        tay
        asl 
        tay
        dey
        dey
        
scroll: lda snake,y
        sta snake+2,y
        lda snake+1,y
        sta snake+3,y
        dey
        dey
        bpl scroll
        lda foo+1
        sta snake
        lda foo+2
        sta snake+1
        
        rts
}

msound: {
        lda #15
        sta SID+24      //volume
        lda #25
        sta SID+1       //voice 1, frequency high-byte
        lda #9
        sta SID+5       //attack/decay
        lda #2
        sta SID+6       //sustain/release
        lda #17
        sta SID+4       //waveform (17=triangle)
        lda #16
        sta SID+4       
        rts
}
mframe: .byte   SPEED
pos: .word 1024+1+12*40
vel: .word 1
slen:   .byte 15
snake:  .word 128,1024  
info: .text " use wasd keys..."
infoend: .byte 0

//Slammer's example, but adapted by Cruzer
.var spriteData = $3000
.pc = spriteData "spriteData"
.var spritePic = LoadPicture("GetReady96x21.png", List().add($000000,$ffffff,$6c6c6c,$959595))
.for (var i=0; i<4; i++)
        :getSprite(spritePic, i)

.macro getSprite(spritePic, spriteNo) {
        .for (var y=0; y<21; y++)
                .for (var x=0; x<3; x++)
                        .byte spritePic.getSinglecolorByte(x + spriteNo * 3, y) 
        .byte 0
}

//---------------------------------------------------------
.pc=music.location "Music"
.fill music.size, music.getData(i)

//----------------------------------------------------------
// Print the music info while assembling
.print ""
.print "SID Data"
.print "--------"
.print "location=$"+toHexString(music.location)
.print "init=$"+toHexString(music.init)
.print "play=$"+toHexString(music.play)
.print "songs="+music.songs
.print "startSong="+music.startSong
.print "size=$"+toHexString(music.size)
.print "name="+music.name
.print "author="+music.author
.print "copyright="+music.copyright
.print  ""
.print "Additional tech data"
.print "--------------------"
.print "header="+music.header
.print "header version="+music.version
.print "flags="+toBinaryString(music.flags)
.print "speed="+toBinaryString(music.speed)
.print "startpage="+music.startpage
.print "pagelength="+music.pagelength


